﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using Common;
using ThreeItems;

namespace ThreeItems
{
    public class DecentralizedGridSearchAlg
    {
        public void RunComputing(ExampleInfo example)
        {
            double u1 = example.U1;
            double u2 = example.U2;
            double u3 = example.U3;

            double o1 = example.O1;
            double o2 = example.O2;
            double o3 = example.O3;

            double e1 = example.E1;
            double e2 = example.E2;
            double e3 = example.E3;

            double sd1 = example.SD1;
            double sd2 = example.SD2;
            double sd3 = example.SD3;

            double var1 = sd1 * sd1;
            double var2 = sd2 * sd2;
            double var3 = sd3 * sd3;

            double r12 = example.R12;
            double r13 = example.R13;
            double r21 = example.R21;
            double r23 = example.R23;
            double r31 = example.R31;
            double r32 = example.R32;

            double uo1 = example.UO1;
            double uo2 = example.UO2;
            double uo3 = example.UO3;


            //3个组合 从低到高
            //先计算下届和上届
            double pnorm1 = (u1 + r12 * (u2 + o2) + r13 * (u3 + o3)) / (u1 + o1 + r12 * (u2 + o2) + r13 * (u3 + o3));
            example.MaxQC1 = NormDistHelper.QNorm(pnorm1, e1, sd1);
            double pnorm2 = (u2 + r21 * (u1 + o1) + r23 * (u3 + o3)) / (u2 + o2 + r21 * (u1 + o1) + r23 * (u3 + o3));
            example.MaxQC2 = NormDistHelper.QNorm(pnorm2, e2, sd2);
            double pnorm3 = (u3 + r31 * (u1 + o1) + r32 * (u2 + o2)) / (u3 + o3 + r31 * (u1 + o1) + r32 * (u2 + o2));
            example.MaxQC3 = NormDistHelper.QNorm(pnorm3, e3, sd3);

            double e1_e = e1 - r21 * e2 - r31 * e3;
            double e2_e = e2 - r12 * e1 - r32 * e3;
            double e3_e = e3 - r13 * e1 - r23 * e2;

            double sd1_e = Math.Sqrt(var1 + Math.Pow(r21 * sd2, 2) + Math.Pow(r31 * sd3, 2));
            double sd2_e = Math.Sqrt(var2 + Math.Pow(r12 * sd1, 2) + Math.Pow(r32 * sd3, 2));
            double sd3_e = Math.Sqrt(var3 + Math.Pow(r13 * sd1, 2) + Math.Pow(r23 * sd2, 2));


            example.MinQC1 = NormDistHelper.QNorm(uo1, e1_e, sd1_e);
            example.MinQC2 = NormDistHelper.QNorm(uo2, e2_e, sd2_e);
            example.MinQC3 = NormDistHelper.QNorm(uo3, e3_e, sd3_e);

            CentralizedAlg centralizedAlg = new CentralizedAlg();
            centralizedAlg.ProfitMethod = ProfitType.Approximation;

            double qc1 = (int)Math.Floor(example.MinQC1);
            double qc2 = (int)Math.Floor(example.MinQC2);
            double qc3 = (int)Math.Floor(example.MinQC3);
            double pc = double.NegativeInfinity;

            int total = ((int)Math.Ceiling(example.MaxQC1) + 1 - (int)Math.Floor(example.MinQC1))
                        * ((int)Math.Ceiling(example.MaxQC2) + 1 - (int)Math.Floor(example.MinQC2))
                        * ((int)Math.Ceiling(example.MaxQC3) + 1 - (int)Math.Floor(example.MinQC3));

            int index = 0;
            //开始组合 计算
            for (int i = (int)Math.Floor(example.MinQC1); i < (int)Math.Ceiling(example.MaxQC1) + 1; i++)
            {
                for (int j = (int)Math.Floor(example.MinQC2); j < (int)Math.Ceiling(example.MaxQC2) + 1; j++)
                {
                    for (int k = (int)Math.Floor(example.MinQC3); k < (int)Math.Ceiling(example.MaxQC3) + 1; k++)
                    {
                        index += 1;

                        example.QC1 = i;
                        example.QC1 = j;
                        example.QC1 = k;

                        centralizedAlg.ComputeProfit(example);
                        if (example.PC > pc)
                        {
                            qc1 = example.QC1;
                            qc2 = example.QC2;
                            qc3 = example.QC3;
                            pc = example.PC;
                        }
                        Trace.WriteLine(index * 100 / total + "%");
                    }
                }
            }
            example.QC1 = qc1;
            example.QC2 = qc2;
            example.QC3 = qc3;
            centralizedAlg.ComputeProfit(example);
            DataGateWay.UpdateCentralizedModel(example);
        }
    }
}
